/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package cult.ticketing.action;

import cult.ticketing.bean.House;
import cult.ticketing.bean.Member;
import cult.ticketing.bean.Movie;
import cult.ticketing.bean.ScheduleItem;
import cult.ticketing.dao.HouseDAO;
import cult.ticketing.dao.MemberDAO;
import cult.ticketing.dao.MovieDAO;
import cult.ticketing.dao.ScheduleItemDAO;
import cult.ticketing.processor.PaymentProcessor;
import cult.ticketing.processor.PurchaseProcessor;
import cult.ticketing.processor.Register;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 *
 * @author 51158282
 */
public class TicketingServlet extends HttpServlet {
    private final int AVAILABLE_SEAT = 0;
    private final int BOOKED_SEAT = 1;
    private final int NOT_AVAILABLE_SEAT = 2;
    private final int NOT_A_SEAT = -1;
    private final String MANAGER = "manager";
    private final String OFFICER = "officer";
    private final String CUSTOMER = "customer";


    /** 
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
/*
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        try {
            // output your page here
            out.println("<html>");
            out.println("<head>");
            out.println("<title>Servlet TicketingServlet</title>");  
            out.println("</head>");
            out.println("<body>");
            out.println("<h1>Servlet TicketingServlet at " + request.getContextPath () + "</h1>");
            out.println("</body>");
            out.println("</html>");
            
        } finally { 
            out.close();
        }
    } 
*/
    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String jspPage = this.doIndexPage(request, response);

        this.dispatchJsp(jspPage, request, response);
    }

    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String jspPage = "";

        if ("login".equalsIgnoreCase(request.getParameter("todo")))
            jspPage = this.doLoginPage(request, response);
        else if ("logout".equalsIgnoreCase(request.getParameter("todo")))
            jspPage = this.doLogoutPage(request, response);
        else if ("doupdate".equalsIgnoreCase(request.getParameter("todo")))
            jspPage = this.doUpdatePage(request, response);
        else if ("showAllMovies".equalsIgnoreCase(request.getParameter("todo")))
            jspPage = this.doShowAllMovies(request, response);
        else if ("searchMovie".equalsIgnoreCase(request.getParameter("todo")))
            jspPage = this.doSearchMovie(request, response);
        else if ("sortMovie".equalsIgnoreCase(request.getParameter("todo")))
            jspPage = this.doSortMovie(request, response);
        else if ("showScheduleItems".equalsIgnoreCase(request.getParameter("todo")))
            jspPage = this.doShowScheduleItems(request, response);
        else if ("showSeatingPlan".equalsIgnoreCase(request.getParameter("todo")))
            jspPage = this.doShowSeatingPlan(request, response);
        else if ("showCostSummary".equalsIgnoreCase(request.getParameter("todo")))
            jspPage = this.doPreparePurchase(request, response);
        else if ("purchase".equalsIgnoreCase(request.getParameter("todo")))
            jspPage = this.doPurchase(request, response);
        else if ("signUp".equalsIgnoreCase(request.getParameter("todo")))
            jspPage = this.signUp(request, response);
        else if ("doSignup".equalsIgnoreCase(request.getParameter("todo")))
            jspPage = this.doSignup(request, response);
        else 
            jspPage = this.doIndexPage(request, response);


        this.dispatchJsp(jspPage, request, response);
    }

    private void dispatchJsp(String jspPage, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.getRequestDispatcher(jspPage).forward(request, response);
    }

    /**
     * Log in a member
     * @param request
     * @param response
     * @return
     * @throws ServletException
     * @throws IOException
     */
    private String doLoginPage(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HttpSession session = request.getSession(true);
        String email = request.getParameter("email");
        String pwd = request.getParameter("password");
        String msg = "";

        MemberDAO memberDAO = new MemberDAO();
        Member member = memberDAO.getMemberByEmail(email);

        if (member == null){
            //no such member
            msg = "This email address is not registered. Please sign up first.";
            session.setAttribute("loginResult", false);
        }
        else if (!member.getPwd().equals(pwd)) {
            // incorrect password   
            msg = "Your password is not correct. Please input again.";
            session.setAttribute("loginResult", false);
        }
        else {
            if (member.getLoginStatus() == true) {
                // already logged in elsewhere
                msg = "You have already logged in elsewhere. Please log off before you do another login.";
                session.setAttribute("loginResult", false);
            }
            else {
                session.setAttribute("loginResult", true);
                String role = member.getRole();
                int memberId = member.getId();
                session.setAttribute("memberId", memberId);
                session.setAttribute("email", email);
                session.setAttribute("role", role);
                memberDAO.updateLoginStatusById(memberId, true);
            }
        }
        session.setAttribute("msg", msg);

        return "jsp/index.jsp";
    }

    /**
     * Log out a member
     * @param request
     * @param response
     * @return
     * @throws ServletException
     * @throws IOException
     */
    private String doLogoutPage(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HttpSession session = request.getSession(true);
        int memberId =(Integer)session.getAttribute("memberId");
        MemberDAO memberDAO = new MemberDAO();
        memberDAO.updateLoginStatusById(memberId, false);
        session.removeAttribute("memberId");
        session.removeAttribute("email");
        session.removeAttribute("role");
        session.removeAttribute("loginResult");
        session.removeAttribute("msg");

        return "/jsp/index.jsp";
    }

    /**
     * Show all movies
     * @param request
     * @param response
     * @return
     * @throws ServletException
     * @throws IOException
     */
    private String doShowAllMovies(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        boolean movieStatus = Boolean.parseBoolean(request.getParameter("movieStatus"));
        MovieDAO movieDAO = new MovieDAO();

        request.setAttribute("movies", movieDAO.getAllMovies(movieStatus));
        
        return "/jsp/now_showing.jsp";
    }

    /**
     * Search a movie
     * @param request
     * @param response
     * @return
     * @throws ServletException
     * @throws IOException
     */
    private String doSearchMovie (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String title = request.getParameter("title");
        MovieDAO movieDAO = new MovieDAO();

        request.setAttribute("movie", movieDAO.getMovieByTitle(title));

        return "";
    }

    private String doSortMovie (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO sort logic

        //request.setAttribute("movies", movies);

        return "";
    }

    private String doShowScheduleItems (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        int movieId = Integer.parseInt(request.getParameter("movieId"));
        ScheduleItemDAO scheduleItemDAO = new ScheduleItemDAO();
        
        request.setAttribute("scheduleItems", scheduleItemDAO.getScheduleItemByMovie(movieId));

        return "/jsp/schedule_item.jsp";
    }

    private String doShowSeatingPlan (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HttpSession session = request.getSession(true);
        if (session.getAttribute("role") != null && ((String)session.getAttribute("role")).equalsIgnoreCase(MANAGER))
            return "/jsp/index.jsp";

        int scheduleItemId = Integer.parseInt(request.getParameter("scheduleItemId"));

        ScheduleItemDAO scheduleItemDAO = new ScheduleItemDAO();
        ScheduleItem scheduleItem = scheduleItemDAO.getScheduleItemById(scheduleItemId);

        int houseId = scheduleItem.getHouseId();
        HouseDAO houseDAO = new HouseDAO();
        House house = houseDAO.getHouseById(houseId);
        int blockOneWidth = house.getBlockOneWidth();
        int blockTwoWidth = house.getBlockTwoWidth();
        int blockThreeWidth = house.getBlockThreeWidth();
        int houseWidth = blockOneWidth + blockTwoWidth + blockThreeWidth;
        int houseHeight = house.getHouseHeight();
        int blockCount = House.BLOCK_COUNT;
        int seatingPlanWidth = houseWidth + blockCount - 1;

        int[][] seatingPlan = new int[houseHeight][seatingPlanWidth];
        int[][] seatAvailability = new int [houseHeight][seatingPlanWidth];

        for (int i=0; i<houseHeight; i++) {
            int seatIndex = 1;
            for (int j=0; j<seatingPlanWidth; j++) {
                if ((j == blockOneWidth) || (j == blockOneWidth + blockTwoWidth + 1)){
                    seatingPlan[i][j] = NOT_A_SEAT;
                    seatAvailability[i][j] = NOT_A_SEAT;
                }
                else {
                    seatingPlan[i][j] = seatIndex;
                    seatIndex ++;
                    seatAvailability[i][j] = AVAILABLE_SEAT;
                }
            }
        }

        String bookedSeat = scheduleItem.getBookedSeat();
        String naSeat = scheduleItem.getNaSeat();

        String[] bookedSeatArr = bookedSeat.split(";");
        String[] naSeatArr = naSeat.split(";");

        for (int i=0; i<bookedSeatArr.length; i++){
            String[] xy = bookedSeatArr[i].split(",");
            int x = Integer.parseInt(xy[0]);
            int y = Integer.parseInt(xy[1]);
            seatAvailability[x][y] = BOOKED_SEAT;
        }

        for (int i=0; i<naSeatArr.length; i++){
            String[] xy = naSeatArr[i].split(",");
            int x = Integer.parseInt(xy[0]);
            int y = Integer.parseInt(xy[1]);
            seatAvailability[x][y] = NOT_AVAILABLE_SEAT;
        }

        session.setAttribute("scheduleItemId", scheduleItemId);
        
        request.setAttribute("seatingPlan", seatingPlan);
        request.setAttribute("seatAvailability", seatAvailability);
        request.setAttribute("houseHeight", houseHeight);
        request.setAttribute("seatingPlanWidth", seatingPlanWidth);

        return "/jsp/seating_plan.jsp";
    }

    private String doPreparePurchase (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HttpSession session = request.getSession(true);
        String seatIndex = request.getParameter("purchasedSeatIndex");
        int scheduleItemId = (Integer)session.getAttribute("scheduleItemId");

        PurchaseProcessor purchaseProcessor = new PurchaseProcessor(scheduleItemId);
        int totalCost = purchaseProcessor.calculatePurchase(seatIndex);
        session.setAttribute("totalCost", totalCost);
        session.setAttribute("seatIndex", seatIndex);   
        String role = (String)session.getAttribute("role");



        if (role != null && role.equalsIgnoreCase(CUSTOMER)) {
            int memberId = (Integer)session.getAttribute("memberId");
            MemberDAO memberDAO = new MemberDAO();
            int loyaltyPoint = memberDAO.getLoyaltyPointById(memberId);
            session.setAttribute("loyaltyPoint", loyaltyPoint);

            if (loyaltyPoint >= totalCost)
                request.setAttribute("isEnoughLoyaltyPoint", "true");
            else
                request.setAttribute("isEnoughLoyaltyPoint", "false");
        }

        return "/jsp/cost_summary.jsp";
    }

    private String doPurchase (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        boolean isSuccessful = false;
        HttpSession session = request.getSession(true);
        String seatIndex = session.getAttribute("seatIndex").toString();
        int scheduleItemId = (Integer)session.getAttribute("scheduleItemId");
        int memberId = -1;
        String email = "";
        
        if (session.getAttribute("memberId") != null) {
            memberId = (Integer)session.getAttribute("memberId");
            email = (String)session.getAttribute("email");
        }else {
            email = request.getParameter("email");
        }

        PurchaseProcessor purchaseProcessor = new PurchaseProcessor(memberId, scheduleItemId, email);
        if(purchaseProcessor.purchaseTicket(seatIndex)) {
            isSuccessful = true;
        }

        session.removeAttribute("scheduleItemId");
        session.removeAttribute("seatIndex");
        session.removeAttribute("totalCost");

        ScheduleItemDAO scheduleItemDAO = new ScheduleItemDAO();
        ScheduleItem scheduleItem = scheduleItemDAO.getScheduleItemById(scheduleItemId);
        int movieId = scheduleItem.getMovieId();
        MovieDAO movieDAO = new MovieDAO();
        Movie movie = movieDAO.getMovieById(movieId);
        String movieTitle = movie.getTitle();
        String showTime = scheduleItem.getShowTime();
        
        request.setAttribute("movieTitle", movieTitle);
        request.setAttribute("showTime", showTime);
        request.setAttribute("seatIndex", seatIndex);
        request.setAttribute("purchaseResult", isSuccessful);

        return "/jsp/purchase_result.jsp";
    }

    private String doIndexPage(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /*TODO Homepage
        GuestDAO guestDAO = new GuestDAO();
        request.setAttribute("guests", guestDAO.getGuests());
         */
        
        return "/jsp/index.jsp";
    }

    private String doUpdatePage(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /*

        Guest guest = new Guest();
        guest.setEmail(request.getParameter("email"));
        guest.setTitle(request.getParameter("title"));
        guest.setName(request.getParameter("name"));
        guest.setPhone(request.getParameter("phone"));
        request.setAttribute("guest", guest);

        GuestDAO guestDAO = new GuestDAO();
        switch (guestDAO.updateGuest(guest)) {
           case OK: request.setAttribute("msg", "Updated guest details successfully.");
           break;
           case FAIL: request.setAttribute("msg", "Sorry, something failed. Guest details not updated.");
        }
         
         */

        return "";
    }

    private String signUp(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        /*MemberDAO memberDAO = new MemberDAO();
        request.setAttribute("movie", MemberDAO.addNewMember(title));*/
        return "jsp/signup.jsp";
    }

    private String doSignup(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        HttpSession session = request.getSession(true);
        MemberDAO memberDAO = new MemberDAO();
        String email = request.getParameter("emailaddress");
        String pwd = request.getParameter("pwd");
        request.setAttribute("email", email);
        request.setAttribute("pwd", pwd);

        
        memberDAO.addNewMember(email,pwd,"costomer");
        return "jsp/index.jsp";
    }
 // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">

    /** 
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>

}
